        <!DOCTYPE html>
        <html>
        <head>
                <meta charset="utf-8">
        <title>Mock class / mock Library / Dart Documentation</title>
        <link rel="stylesheet" type="text/css"
            href="../styles.css">
        <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800" rel="stylesheet" type="text/css">
        <link rel="shortcut icon" href="../favicon.ico">
        
        </head>
        <body data-library="mock" data-type="Mock">
        <div class="page">
        <div class="header">
          <a href="../index.html"><div class="logo"></div></a>
          <a href="../index.html">Dart Documentation</a>
         &rsaquo; <a href="../mock.html">mock</a> &rsaquo; <a href="../mock/Mock.html">Mock</a>        <div id="search-box">
          <input type="search" name="q" id="q" autocomplete="off"
              class="search-input" placeholder="Search API">
        </div>
        
      </div>
      <div class="drop-down" id="drop-down"></div>
      
        <div class="nav">
        
</div>
<div class="content">
        <h2><strong>Mock</strong>
          class
        </h2>
        
<button id="show-inherited" class="show-inherited">Hide inherited</button>
<div class="doc">
<p>The base class for all mocked objects. </p>
<pre class="source">
class Mock {
 /** The mock name. Needed if the log is shared; optional otherwise. */
 final String name;

 /** The set of [Behavior]s supported. */
 Map&lt;String,Behavior&gt; _behaviors;

 /** The [log] of calls made. Only used if [name] is null. */
 LogEntryList log;

 /** How to handle unknown method calls - swallow or throw. */
 final bool _throwIfNoBehavior;

 /** Whether to create an audit log or not. */
 bool _logging;

 bool get logging =&gt; _logging;
 set logging(bool value) {
   if (value &amp;&amp; log == null) {
     log = new LogEntryList();
   }
   _logging = value;
 }

 /**
  * Default constructor. Unknown method calls are allowed and logged,
  * the mock has no name, and has its own log.
  */
 Mock() : _throwIfNoBehavior = false, log = null, name = null {
   logging = true;
   _behaviors = new Map&lt;String,Behavior&gt;();
 }

 /**
  * This constructor makes a mock that has a [name] and possibly uses
  * a shared [log]. If [throwIfNoBehavior] is true, any calls to methods
  * that have no defined behaviors will throw an exception; otherwise they
  * will be allowed and logged (but will not do anything).
  * If [enableLogging] is false, no logging will be done initially (whether
  * or not a [log] is supplied), but [logging] can be set to true later.
  */
 Mock.custom({this.name,
              this.log,
              throwIfNoBehavior: false,
              enableLogging: true}) : _throwIfNoBehavior = throwIfNoBehavior {
   if (log != null &amp;&amp; name == null) {
     throw new Exception("Mocks with shared logs must have a name.");
   }
   logging = enableLogging;
   _behaviors = new Map&lt;String,Behavior&gt;();
 }

 /**
  * [when] is used to create a new or extend an existing [Behavior].
  * A [CallMatcher] [filter] must be supplied, and the [Behavior]s for
  * that signature are returned (being created first if needed).
  *
  * Typical use case:
  *
  *     mock.when(callsTo(...)).alwaysReturn(...);
  */
 Behavior when(CallMatcher logFilter) {
   String key = logFilter.toString();
   if (!_behaviors.containsKey(key)) {
     Behavior b = new Behavior(logFilter);
     _behaviors[key] = b;
     return b;
   } else {
     return _behaviors[key];
   }
 }

 /**
  * This is the handler for method calls. We loop through the list
  * of [Behavior]s, and find the first match that still has return
  * values available, and then do the action specified by that
  * return value. If we find no [Behavior] to apply an exception is
  * thrown.
  */
 noSuchMethod(InvocationMirror invocation) {
   var method = invocation.memberName;
   var args = invocation.positionalArguments;
   if (invocation.isGetter) {
     method = 'get $method';
   } else if (invocation.isSetter) {
     method = 'set $method';
     // Remove the trailing '='.
     if (method[method.length-1] == '=') {
       method = method.substring(0, method.length - 1);
     }
   }
   bool matchedMethodName = false;
   MatchState matchState = new MatchState();
   for (String k in _behaviors.keys) {
     Behavior b = _behaviors[k];
     if (b.matcher.nameFilter.matches(method, matchState)) {
       matchedMethodName = true;
     }
     if (b.matches(method, args)) {
       List actions = b.actions;
       if (actions == null || actions.length == 0) {
         continue; // No return values left in this Behavior.
       }
       // Get the first response.
       Responder response = actions[0];
       // If it is exhausted, remove it from the list.
       // Note that for endlessly repeating values, we started the count at
       // 0, so we get a potentially useful value here, which is the
       // (negation of) the number of times we returned the value.
       if (--response.count == 0) {
         actions.removeRange(0, 1);
       }
       // Do the response.
       Action action = response.action;
       var value = response.value;
       if (action == Action.RETURN) {
         if (_logging &amp;&amp; b.logging) {
           log.add(new LogEntry(name, method, args, action, value));
         }
         return value;
       } else if (action == Action.THROW) {
         if (_logging &amp;&amp; b.logging) {
           log.add(new LogEntry(name, method, args, action, value));
         }
         throw value;
       } else if (action == Action.PROXY) {
         // TODO(gram): Replace all this with:
         //     var rtn = invocation.invokeOn(value);
         // once that is supported.
         var rtn;
         switch (args.length) {
           case 0:
             rtn = value();
             break;
           case 1:
             rtn = value(args[0]);
             break;
           case 2:
             rtn = value(args[0], args[1]);
             break;
           case 3:
             rtn = value(args[0], args[1], args[2]);
             break;
           case 4:
             rtn = value(args[0], args[1], args[2], args[3]);
             break;
           case 5:
             rtn = value(args[0], args[1], args[2], args[3], args[4]);
             break;
           case 6:
             rtn = value(args[0], args[1], args[2], args[3],
                 args[4], args[5]);
             break;
           case 7:
             rtn = value(args[0], args[1], args[2], args[3],
                 args[4], args[5], args[6]);
             break;
           case 8:
             rtn = value(args[0], args[1], args[2], args[3],
                 args[4], args[5], args[6], args[7]);
             break;
           case 9:
             rtn = value(args[0], args[1], args[2], args[3],
                 args[4], args[5], args[6], args[7], args[8]);
             break;
           case 9:
             rtn = value(args[0], args[1], args[2], args[3],
                 args[4], args[5], args[6], args[7], args[8], args[9]);
             break;
           default:
             throw new Exception(
                 "Cannot proxy calls with more than 10 parameters.");
         }
         if (_logging &amp;&amp; b.logging) {
           log.add(new LogEntry(name, method, args, action, rtn));
         }
         return rtn;
       }
     }
   }
   if (matchedMethodName) {
     // User did specify behavior for this method, but all the
     // actions are exhausted. This is considered an error.
     throw new Exception('No more actions for method '
         '${_qualifiedName(name, method)}.');
   } else if (_throwIfNoBehavior) {
     throw new Exception('No behavior specified for method '
         '${_qualifiedName(name, method)}.');
   }
   // Otherwise user hasn't specified behavior for this method; we don't throw
   // so we can underspecify.
   if (_logging) {
     log.add(new LogEntry(name, method, args, Action.IGNORE));
   }
 }

 /** [verifyZeroInteractions] returns true if no calls were made */
 bool verifyZeroInteractions() {
   if (log == null) {
     // This means we created the mock with logging off and have never turned
     // it on, so it doesn't make sense to verify behavior on such a mock.
     throw new
         Exception("Can't verify behavior when logging was never enabled.");
   }
   return log.logs.length == 0;
 }

 /**
  * [getLogs] extracts all calls from the call log that match the
  * [logFilter], and returns the matching list of [LogEntry]s. If
  * [destructive] is false (the default) the matching calls are left
  * in the log, else they are removed. Removal allows us to verify a
  * set of interactions and then verify that there are no other
  * interactions left. [actionMatcher] can be used to further
  * restrict the returned logs based on the action the mock performed.
  * [logFilter] can be a [CallMatcher] or a predicate function that
  * takes a [LogEntry] and returns a bool.
  *
  * Typical usage:
  *
  *     getLogs(callsTo(...)).verify(...);
  */
 LogEntryList getLogs([CallMatcher logFilter,
                       Matcher actionMatcher,
                       bool destructive = false]) {
   if (log == null) {
     // This means we created the mock with logging off and have never turned
     // it on, so it doesn't make sense to get logs from such a mock.
     throw new
         Exception("Can't retrieve logs when logging was never enabled.");
   } else {
     return log.getMatches(name, logFilter, actionMatcher, destructive);
   }
 }

 /**
  * Useful shorthand method that creates a [CallMatcher] from its arguments
  * and then calls [getLogs].
  */
 LogEntryList calls(method,
                     [arg0 = _noArg,
                      arg1 = _noArg,
                      arg2 = _noArg,
                      arg3 = _noArg,
                      arg4 = _noArg,
                      arg5 = _noArg,
                      arg6 = _noArg,
                      arg7 = _noArg,
                      arg8 = _noArg,
                      arg9 = _noArg]) =&gt;
     getLogs(callsTo(method, arg0, arg1, arg2, arg3, arg4,
         arg5, arg6, arg7, arg8, arg9));

 /** Clear the behaviors for the Mock. */
 void resetBehavior() =&gt; _behaviors.clear();

 /** Clear the logs for the Mock. */
 void clearLogs() {
   if (log != null) {
     if (name == null) { // This log is not shared.
       log.logs.clear();
     } else { // This log may be shared.
       log.logs = log.logs.where((e) =&gt; e.mockName != name).toList();
     }
   }
 }

 /** Clear both logs and behavior. */
 void reset() {
   resetBehavior();
   clearLogs();
 }
}
</pre>
</div>
<div>
<h3>Constructors</h3>
<div class="method"><h4 id="Mock">
<button class="show-code">Code</button>
new <strong>Mock</strong>() <a class="anchor-link" href="#Mock"
              title="Permalink to Mock.Mock">#</a></h4>
<div class="doc">
<p>Default constructor. Unknown method calls are allowed and logged,
the mock has no name, and has its own log.</p>
<pre class="source">
Mock() : _throwIfNoBehavior = false, log = null, name = null {
 logging = true;
 _behaviors = new Map&lt;String,Behavior&gt;();
}
</pre>
</div>
</div>
<div class="method"><h4 id="Mock.custom">
<button class="show-code">Code</button>
new <strong>Mock.custom</strong>({String name, <a href="../mock/LogEntryList.html">LogEntryList</a> log, throwIfNoBehavior: false, enableLogging: true}) <a class="anchor-link" href="#Mock.custom"
              title="Permalink to Mock.Mock.custom">#</a></h4>
<div class="doc">
<p>This constructor makes a mock that has a 
<span class="param">name</span> and possibly uses
a shared 
<span class="param">log</span>. If 
<span class="param">throwIfNoBehavior</span> is true, any calls to methods
that have no defined behaviors will throw an exception; otherwise they
will be allowed and logged (but will not do anything).
If 
<span class="param">enableLogging</span> is false, no logging will be done initially (whether
or not a 
<span class="param">log</span> is supplied), but <a class="crossref" href="../mock/Mock.html#logging">logging</a> can be set to true later.</p>
<pre class="source">
Mock.custom({this.name,
            this.log,
            throwIfNoBehavior: false,
            enableLogging: true}) : _throwIfNoBehavior = throwIfNoBehavior {
 if (log != null &amp;&amp; name == null) {
   throw new Exception("Mocks with shared logs must have a name.");
 }
 logging = enableLogging;
 _behaviors = new Map&lt;String,Behavior&gt;();
}
</pre>
</div>
</div>
</div>
<div>
<h3>Properties</h3>
<div class="field"><h4 id="log">
<button class="show-code">Code</button>
<a href="../mock/LogEntryList.html">LogEntryList</a>         <strong>log</strong> <a class="anchor-link"
            href="#log"
            title="Permalink to Mock.log">#</a>
        </h4>
        <div class="doc">
<pre class="source">
log
</pre>
</div>
</div>
<div class="field"><h4 id="logging">
<button class="show-code">Code</button>
bool         <strong>logging</strong> <a class="anchor-link"
            href="#logging"
            title="Permalink to Mock.logging">#</a>
        </h4>
        <div class="doc">
<pre class="source">
bool get logging =&gt; _logging;
</pre>
<pre class="source">
set logging(bool value) {
 if (value &amp;&amp; log == null) {
   log = new LogEntryList();
 }
 _logging = value;
}
</pre>
</div>
</div>
<div class="field"><h4 id="name">
<button class="show-code">Code</button>
final String         <strong>name</strong> <a class="anchor-link"
            href="#name"
            title="Permalink to Mock.name">#</a>
        </h4>
        <div class="doc">
<pre class="source">
name
</pre>
</div>
</div>
</div>
<div>
<h3>Methods</h3>
<div class="method"><h4 id="calls">
<button class="show-code">Code</button>
<a href="../mock/LogEntryList.html">LogEntryList</a> <strong>calls</strong>(method, [arg0 = _noArg, arg1 = _noArg, arg2 = _noArg, arg3 = _noArg, arg4 = _noArg, arg5 = _noArg, arg6 = _noArg, arg7 = _noArg, arg8 = _noArg, arg9 = _noArg]) <a class="anchor-link" href="#calls"
              title="Permalink to Mock.calls">#</a></h4>
<div class="doc">
<p>Useful shorthand method that creates a <a class="crossref" href="../mock/CallMatcher.html">CallMatcher</a> from its arguments
and then calls <a class="crossref" href="../mock/Mock.html#getLogs">getLogs</a>.</p>
<pre class="source">
LogEntryList calls(method,
                   [arg0 = _noArg,
                    arg1 = _noArg,
                    arg2 = _noArg,
                    arg3 = _noArg,
                    arg4 = _noArg,
                    arg5 = _noArg,
                    arg6 = _noArg,
                    arg7 = _noArg,
                    arg8 = _noArg,
                    arg9 = _noArg]) =&gt;
   getLogs(callsTo(method, arg0, arg1, arg2, arg3, arg4,
       arg5, arg6, arg7, arg8, arg9));
</pre>
</div>
</div>
<div class="method"><h4 id="clearLogs">
<button class="show-code">Code</button>
void <strong>clearLogs</strong>() <a class="anchor-link" href="#clearLogs"
              title="Permalink to Mock.clearLogs">#</a></h4>
<div class="doc">
<p>Clear the logs for the Mock. </p>
<pre class="source">
void clearLogs() {
 if (log != null) {
   if (name == null) { // This log is not shared.
     log.logs.clear();
   } else { // This log may be shared.
     log.logs = log.logs.where((e) =&gt; e.mockName != name).toList();
   }
 }
}
</pre>
</div>
</div>
<div class="method"><h4 id="getLogs">
<button class="show-code">Code</button>
<a href="../mock/LogEntryList.html">LogEntryList</a> <strong>getLogs</strong>([<a href="../mock/CallMatcher.html">CallMatcher</a> logFilter, <a href="../matcher/Matcher.html">Matcher</a> actionMatcher, bool destructive = false]) <a class="anchor-link" href="#getLogs"
              title="Permalink to Mock.getLogs">#</a></h4>
<div class="doc">
<p><a class="crossref" href="../mock/Mock.html#getLogs">getLogs</a> extracts all calls from the call log that match the

<span class="param">logFilter</span>, and returns the matching list of <a class="crossref" href="../mock/LogEntry.html">LogEntry</a>s. If

<span class="param">destructive</span> is false (the default) the matching calls are left
in the log, else they are removed. Removal allows us to verify a
set of interactions and then verify that there are no other
interactions left. 
<span class="param">actionMatcher</span> can be used to further
restrict the returned logs based on the action the mock performed.

<span class="param">logFilter</span> can be a <a class="crossref" href="../mock/CallMatcher.html">CallMatcher</a> or a predicate function that
takes a <a class="crossref" href="../mock/LogEntry.html">LogEntry</a> and returns a bool.</p>
<p>Typical usage:</p>
<pre><span class="i ">getLogs</span><span class="p ">(</span><span class="i ">callsTo</span><span class="p ">(</span>...<span class="p ">)</span><span class="p ">)</span><span class="p ">.</span><span class="i ">verify</span><span class="p ">(</span>...<span class="p ">)</span><span class="p ">;</span></pre>
<pre class="source">
LogEntryList getLogs([CallMatcher logFilter,
                     Matcher actionMatcher,
                     bool destructive = false]) {
 if (log == null) {
   // This means we created the mock with logging off and have never turned
   // it on, so it doesn't make sense to get logs from such a mock.
   throw new
       Exception("Can't retrieve logs when logging was never enabled.");
 } else {
   return log.getMatches(name, logFilter, actionMatcher, destructive);
 }
}
</pre>
</div>
</div>
<div class="method"><h4 id="noSuchMethod">
<button class="show-code">Code</button>
<strong>noSuchMethod</strong>(InvocationMirror invocation) <a class="anchor-link" href="#noSuchMethod"
              title="Permalink to Mock.noSuchMethod">#</a></h4>
<div class="doc">
<p>This is the handler for method calls. We loop through the list
of <a class="crossref" href="../mock/Behavior.html">Behavior</a>s, and find the first match that still has return
values available, and then do the action specified by that
return value. If we find no <a class="crossref" href="../mock/Behavior.html">Behavior</a> to apply an exception is
thrown.</p>
<pre class="source">
noSuchMethod(InvocationMirror invocation) {
 var method = invocation.memberName;
 var args = invocation.positionalArguments;
 if (invocation.isGetter) {
   method = 'get $method';
 } else if (invocation.isSetter) {
   method = 'set $method';
   // Remove the trailing '='.
   if (method[method.length-1] == '=') {
     method = method.substring(0, method.length - 1);
   }
 }
 bool matchedMethodName = false;
 MatchState matchState = new MatchState();
 for (String k in _behaviors.keys) {
   Behavior b = _behaviors[k];
   if (b.matcher.nameFilter.matches(method, matchState)) {
     matchedMethodName = true;
   }
   if (b.matches(method, args)) {
     List actions = b.actions;
     if (actions == null || actions.length == 0) {
       continue; // No return values left in this Behavior.
     }
     // Get the first response.
     Responder response = actions[0];
     // If it is exhausted, remove it from the list.
     // Note that for endlessly repeating values, we started the count at
     // 0, so we get a potentially useful value here, which is the
     // (negation of) the number of times we returned the value.
     if (--response.count == 0) {
       actions.removeRange(0, 1);
     }
     // Do the response.
     Action action = response.action;
     var value = response.value;
     if (action == Action.RETURN) {
       if (_logging &amp;&amp; b.logging) {
         log.add(new LogEntry(name, method, args, action, value));
       }
       return value;
     } else if (action == Action.THROW) {
       if (_logging &amp;&amp; b.logging) {
         log.add(new LogEntry(name, method, args, action, value));
       }
       throw value;
     } else if (action == Action.PROXY) {
       // TODO(gram): Replace all this with:
       //     var rtn = invocation.invokeOn(value);
       // once that is supported.
       var rtn;
       switch (args.length) {
         case 0:
           rtn = value();
           break;
         case 1:
           rtn = value(args[0]);
           break;
         case 2:
           rtn = value(args[0], args[1]);
           break;
         case 3:
           rtn = value(args[0], args[1], args[2]);
           break;
         case 4:
           rtn = value(args[0], args[1], args[2], args[3]);
           break;
         case 5:
           rtn = value(args[0], args[1], args[2], args[3], args[4]);
           break;
         case 6:
           rtn = value(args[0], args[1], args[2], args[3],
               args[4], args[5]);
           break;
         case 7:
           rtn = value(args[0], args[1], args[2], args[3],
               args[4], args[5], args[6]);
           break;
         case 8:
           rtn = value(args[0], args[1], args[2], args[3],
               args[4], args[5], args[6], args[7]);
           break;
         case 9:
           rtn = value(args[0], args[1], args[2], args[3],
               args[4], args[5], args[6], args[7], args[8]);
           break;
         case 9:
           rtn = value(args[0], args[1], args[2], args[3],
               args[4], args[5], args[6], args[7], args[8], args[9]);
           break;
         default:
           throw new Exception(
               "Cannot proxy calls with more than 10 parameters.");
       }
       if (_logging &amp;&amp; b.logging) {
         log.add(new LogEntry(name, method, args, action, rtn));
       }
       return rtn;
     }
   }
 }
 if (matchedMethodName) {
   // User did specify behavior for this method, but all the
   // actions are exhausted. This is considered an error.
   throw new Exception('No more actions for method '
       '${_qualifiedName(name, method)}.');
 } else if (_throwIfNoBehavior) {
   throw new Exception('No behavior specified for method '
       '${_qualifiedName(name, method)}.');
 }
 // Otherwise user hasn't specified behavior for this method; we don't throw
 // so we can underspecify.
 if (_logging) {
   log.add(new LogEntry(name, method, args, Action.IGNORE));
 }
}
</pre>
</div>
</div>
<div class="method"><h4 id="reset">
<button class="show-code">Code</button>
void <strong>reset</strong>() <a class="anchor-link" href="#reset"
              title="Permalink to Mock.reset">#</a></h4>
<div class="doc">
<p>Clear both logs and behavior. </p>
<pre class="source">
void reset() {
 resetBehavior();
 clearLogs();
}
</pre>
</div>
</div>
<div class="method"><h4 id="resetBehavior">
<button class="show-code">Code</button>
void <strong>resetBehavior</strong>() <a class="anchor-link" href="#resetBehavior"
              title="Permalink to Mock.resetBehavior">#</a></h4>
<div class="doc">
<p>Clear the behaviors for the Mock. </p>
<pre class="source">
void resetBehavior() =&gt; _behaviors.clear();
</pre>
</div>
</div>
<div class="method"><h4 id="verifyZeroInteractions">
<button class="show-code">Code</button>
bool <strong>verifyZeroInteractions</strong>() <a class="anchor-link" href="#verifyZeroInteractions"
              title="Permalink to Mock.verifyZeroInteractions">#</a></h4>
<div class="doc">
<p><a class="crossref" href="../mock/Mock.html#verifyZeroInteractions">verifyZeroInteractions</a> returns true if no calls were made </p>
<pre class="source">
bool verifyZeroInteractions() {
 if (log == null) {
   // This means we created the mock with logging off and have never turned
   // it on, so it doesn't make sense to verify behavior on such a mock.
   throw new
       Exception("Can't verify behavior when logging was never enabled.");
 }
 return log.logs.length == 0;
}
</pre>
</div>
</div>
<div class="method"><h4 id="when">
<button class="show-code">Code</button>
<a href="../mock/Behavior.html">Behavior</a> <strong>when</strong>(<a href="../mock/CallMatcher.html">CallMatcher</a> logFilter) <a class="anchor-link" href="#when"
              title="Permalink to Mock.when">#</a></h4>
<div class="doc">
<p><a class="crossref" href="../mock/Mock.html#when">when</a> is used to create a new or extend an existing <a class="crossref" href="../mock/Behavior.html">Behavior</a>.
A [CallMatcher] [filter] must be supplied, and the <a class="crossref" href="../mock/Behavior.html">Behavior</a>s for
that signature are returned (being created first if needed).</p>
<p>Typical use case:</p>
<pre><span class="i ">mock</span><span class="p ">.</span><span class="i ">when</span><span class="p ">(</span><span class="i ">callsTo</span><span class="p ">(</span>...<span class="p ">)</span><span class="p ">)</span><span class="p ">.</span><span class="i ">alwaysReturn</span><span class="p ">(</span>...<span class="p ">)</span><span class="p ">;</span></pre>
<pre class="source">
Behavior when(CallMatcher logFilter) {
 String key = logFilter.toString();
 if (!_behaviors.containsKey(key)) {
   Behavior b = new Behavior(logFilter);
   _behaviors[key] = b;
   return b;
 } else {
   return _behaviors[key];
 }
}
</pre>
</div>
</div>
</div>
        </div>
        <div class="clear"></div>
        </div>
        <div class="footer">
          
        </div>
        <script async src="../client-live-nav.js"></script>
        </body></html>
        
